//******************************************************************************
//this code is protected by the GNU affero GPLv3
//author:Sylvain BERTRAND <sylvain.bertrand AT gmail dot com>
//                        <digital.ragnarok AT gmail dot com>
//******************************************************************************
#include "globals.h"

static void obj_release(struct client *c,s32 shm_pool_slot)
{
    c->objs[shm_pool_slot].state=CLIENT_OBJ_INVALID;
    while(1){l r=close(c->objs[shm_pool_slot].pool.fd); if(r!=-EINTR) break;}
}

s8 shm_pool_new_visible(struct client *c,u32 shm_pool_id,i fd,s32 sz)
{
  s8 r=LWL_OK;
  s32 free_slot=CLIENT_FIRST_VALID_ID;
  while(1){
    if(free_slot==CLIENT_OBJS_MAX){
      r=LWL_ERR;
      break;
    }
    if(c->objs[free_slot].state&CLIENT_OBJ_INVALID){
      c->objs[free_slot].state=CLIENT_OBJ_SHM_POOL|CLIENT_OBJ_VISIBLE;
      c->objs[free_slot].release=obj_release;
      c->objs[free_slot].id=shm_pool_id;
      c->objs[free_slot].n=1;//the wire has a reference on it
      c->objs[free_slot].pool.fd=fd;
      c->objs[free_slot].pool.start=0;//XXX:we don't map it
      c->objs[free_slot].pool.sz=sz;
      break;
    }
    ++free_slot;
  }
  return r;
}

s8 shm_pool_create_buffer(struct client *c,s32 shm_pool_slot,
                       u32 shm_pool_buffer_id,s32 offset,s32 w,s32 h,s32 stride,
                                                                        u32 fmt)
{
  s8 r=shm_pool_buffer_new_visible(c,shm_pool_buffer_id,shm_pool_slot,offset,w,
                                                                  h,stride,fmt);
  if(r==LWL_ERR)
    PERR("client(%d):shm_pool::create_buffer unable to create new shm pool"
                                                             " buffer\n",c->so);
  return r;
}

s8 shm_pool_destroy(struct client *c,s32 shm_pool_slot)
{
  s32 n=client_obj_unref(c,shm_pool_slot);
  if(!n) c->objs[shm_pool_slot].state&=~CLIENT_OBJ_VISIBLE;
  return wl_display_ev_delete_id(c,c->objs[shm_pool_slot].id);
}

s8 shm_pool_resize(struct client *c,s32 shm_pool_slot,s32 sz)
{
  c->objs[shm_pool_slot].pool.sz=sz;
  return LWL_OK;
}
